<?php

declare(strict_types=1);

namespace app;

use think\App;
use think\exception\ValidateException;
use think\Validate;

/**
 * 控制器基础类
 */
abstract class BaseController
{
    /**
     * Request实例
     * @var \think\Request
     */
    protected $request;

    /**
     * 应用实例
     * @var \think\App
     */
    protected $app;

    /**
     * 是否批量验证
     * @var bool
     */
    protected $batchValidate = false;

    /**
     * 控制器中间件
     * @var array
     */
    protected $middleware = [];

    /**
     * 构造方法
     * @access public
     * @param  App  $app  应用对象
     */
    public function __construct(App $app)
    {
        $this->app     = $app;
        $this->request = $this->app->request;

        // 控制器初始化
        $this->initialize();
    }

    // 初始化
    protected function initialize() {}

    /**
     * 验证数据
     * @access protected
     * @param  array        $data     数据
     * @param  string|array $validate 验证器名或者验证规则数组
     * @param  array        $message  提示信息
     * @param  bool         $batch    是否批量验证
     * @return array|string|true
     * @throws ValidateException
     */
    protected function validate(array $data, $validate, array $message = [], bool $batch = false)
    {
        if (is_array($validate)) {
            $v = new Validate();
            $v->rule($validate);
        } else {
            if (strpos($validate, '.')) {
                // 支持场景
                [$validate, $scene] = explode('.', $validate);
            }
            $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
            $v     = new $class();
            if (!empty($scene)) {
                $v->scene($scene);
            }
        }

        $v->message($message);

        // 是否批量验证
        if ($batch || $this->batchValidate) {
            $v->batch(true);
        }

        return $v->failException(true)->check($data);
    }
    protected function success($data = null, string $msg = 'success', int $code = 200)
    {
        return json([
            'code' => $code,
            'msg'  => $msg,
            'data' => $data
        ]);
    }

    /**
     * 失败响应
     * @param string $msg 错误信息
     * @param int $code 状态码
     * @param mixed $data 返回数据
     * @return \think\response\Json
     */
    protected function error(string $msg = 'fail', int $code = 400, $data = null)
    {
        return json([
            'code' => $code,
            'msg'  => $msg,
            'data' => $data
        ]);
    }
    /**
     * 构建查询条件
     * @param array $options 配置选项
     * @return array
     */
    protected function buildQueryMap(array $options = [])
    {
        // 获取参数，处理嵌套参数结构
        $allParams = $this->request->param();
        $params = [];

        // 如果存在params键且是数组，则使用params中的参数
        if (isset($allParams['params']) && is_array($allParams['params'])) {
            $params = $allParams['params'];
        } else {
            // 否则使用所有参数
            $params = $allParams;
        }

        $defaultOptions = [
            'ignore_fields' => ['page', 'page_size', 'keyword', "require_seller_id"],
            'date_fields' => ['create_time', 'update_time'],
            'in_fields' => [],
            'like_fields' => []
        ];

        $options = array_merge($defaultOptions, $options);

        // 过滤空值，但保留数组类型参数
        $params = array_filter($params, function ($value) {
            return $value !== '' && $value !== null;
        });

        $map = [];

        foreach ($params as $key => $value) {
            // 忽略指定字段
            if (in_array($key, $options['ignore_fields'])) {
                continue;
            }

            // 处理日期时间范围查询
            if (in_array($key, $options['date_fields']) && is_array($value) && isset($value[0]) && isset($value[1])) {
                // 自动补全时间部分
                $start = $value[0];
                $end = $value[1];

                // 提取日期部分并设置时间范围
                if (preg_match('/^(\d{4}-\d{2}-\d{2})/', $start, $matches)) {
                    $start = $matches[1] . ' 00:00:00';
                }

                if (preg_match('/^(\d{4}-\d{2}-\d{2})/', $end, $matches)) {
                    $end = $matches[1] . ' 23:59:59';
                }

                $map[] = [$key, 'between time', [$start, $end]];
            }
            // 处理 IN 查询
            elseif (in_array($key, $options['in_fields']) && is_array($value)) {
                $map[] = [$key, 'in', $value];
            }
            // 处理 LIKE 查询
            elseif (in_array($key, $options['like_fields'])) {
                $map[] = [$key, 'like', '%' . $value . '%'];
            }
            // 处理普通查询条件，确保值不是数组
            elseif (!is_array($value)) {
                $map[] = [$key, '=', $value];
            }
            // 如果是数组但不是特殊处理类型，则跳过
        }

        return $map;
    }
}
